 BEGIN { print "TALL (timm's awk library, loaded) v0.1" >"/dev/stderr"
         _ = SUBSEP 
         Q = "\"" 
         Pi= 3.1415926535
         Ee= 2.7182818284 
         Inf=10^32
         Pinch=1/Inf
       }
 function resetSeed() {
    srand(Seed ? Seed : systime() + PROCINFO["pid"]) 
 }
 function norm(x,min,max) { 
 	return (x - min)/ (max - min + Pinch) 
 }
 function stddev(n,sum,sumSq,   tmp) {
    tmp = (sumSq-((sum*sum)/n))/(n-1)
	tmp = tmp < 0 ? 0 : tmp
   return sqrt(tmp)
 }
 function gaussianPdf(m,s,x) {
    s = s + Pinch
    return 1/sqrt(2*Pi*s^2)*Ee^(-1*(x-m)^2/(2*s^2))
 }
 function round(x)      { 
	return int(x<0 ? x-0.5 : x+0.5) 
 }
 function push(a,v,old) {
 	old      = length(a)
 	a[old+1] = v
 	return v
 }
 function pop(a,  old,v) {
 	old = length(a)
	v   = a[old]
	delete a[old]
	return v
 }
 function pretty(x) {
	gsub(_,",",x)
    return x
 }
 function o(a, str,control, i,com) {
      str = str ? str : "array"
      com = control ? control : " -n  -k 2" 
      com = "sort " com  " #" rand(); # ensure com is unique
      for(i in a) print oprim(str,i,a) | com;
      close(com) 
  }
 function oprim(str,i,a,  j) {
      j=i
      gsub(SUBSEP,",",j) 
      return str "[ " j " ]\t=\t [ " a[i] " ]"
 }
 function p2a(pairs,a,sep,n,tmp,i) {
	sep = sep ? sep : "/,/"
	n=split(pairs,tmp,sep)
    print n
	for(i=1;i<n;i=i+2) { print i " " tmp[i]
		a[tmp[i]] = tmp[i+1] }
 }
###########quartile() {
 function testquartile(all){
	print 33
 	print split("0 0 0 0 0 0 0 0 0 0 0 0 22 33 33 35 36"\
          " 39 40 44 47 50 51 52 53 53 55 61 62 71",all)
 	quartile(all)
 }
 function quartile(s0,     o,s,n,min,q1,median,q3,max,kludge) {
  p2a("F=5.1f,Low=-,High=+,Median=|,Max=[,Min=],"\
            "Shrink=2,Left=-100,Right=100,Off= " o, ",")
  for(i in o) print i " = " o[i]
	return 1
  n     = asort(s0,s)
  min   = s[1];
  q1    = s[int(n/4)];
  median= s[int(2*n/4)];
  q3    = s[int(3*n/4)];
  max   = s[n];
  printf("%"F",%"F",%"F",%"F",%"F",%s\n",
         min,q1,median,q3,max,
         quartile1(o,min,q1,median,q3,max,o["Right"],o["Shrink"])) 
 }
 function quartile1(o,min,q1,median,q3,max,width, scale,    i,l,str) {
        width  /= scale
        min    /= scale
        q1     /= scale
        median /= scale
        q3     /= scale
        max    /= scale
        for(i=  1; i<=width; i++) l[int(i)]= o["Off"];
        for(i=min;    i<=q1; i++) l[int(i)]= o["Low"]
        for(i= q3;   i<=max; i++) l[int(i)]= o["High"]
        l[int(median)] = o["Median"]
        for(i= 1; i<=width; i++) str = str l[int(i)];
        return o["Min"] str o["Max"]
 }

